// Javascript for sending the new policy to the GCM server.
// And some eventhandling for the html page.
API_URL = 'https://' + window.location.host + '/_ah/api';

if (window.location.hostname == 'localhost'
		|| window.location.hostname == '127.0.0.1'
		|| ((window.location.port != "") && (window.location.port > 999))) {
	// We're probably running against the DevAppServer
	API_URL = 'http://' + window.location.host + '/_ah/api';
}

function showSuccess() {
	$("#alertArea").hide();
	$("#successArea").show();
	$("#successArea").fadeOut(1000);
}

function showError(errorHtml) {
	$("#alertArea").removeClass('alert-error alert-info alert-success')
			.addClass('alert-error');
	$("#alertContentArea").html(errorHtml);
	$("#alertArea").show();
}

function showInfo(infoHtml) {
	$("#alertArea").removeClass('alert-error alert-info alert-success')
			.addClass('alert-info');
	$("#alertContentArea").html(infoHtml);
	$("#alertArea").show();
}

// This method loads the deviceinfoendpoint and messageEndpoint libraries
function loadGapi() {
	gapi.client.load('deviceinfoendpoint', 'v1', function() {
		updateRegisteredDeviceTable();
	});

	gapi.client.load('messageEndpoint', 'v1', function() {
	});
}

// Specialized function for checking error responses; it's needed to work around
// bugs in the current version of the DevAppServer
function checkErrorResponse(result, rawResult) {
	// Generally, !result should never occur. It's a bug with the DevAppServer.
	// It will be fixed
	// in a forthcoming version of App Engine.
	if (!result) {
		try {
			// This is some special exception-handling code to deal with the
			// DevAppServer not
			// handling empty (void responses) from an endpoint method in App
			// Engine 1.7.5.
			result = JSON.parse(rawResult);
		} catch (err) {
			// This is a spurious error. Return true.
			if (rawResult
					.indexOf("Error 400 Failed to parse JSON request: Unexpected character") != -1) {
				return {
					isError : false
				};
			} else {
				if (rawResult == "") {
					// Empty result; perhaps we're disconnected?
					return {
						isError : true,
						errorMessage : "No response from server! Is it up and running?"
					};

				} else {
					// Unknown error; this shouldn't really happen
					var safeErrorHtml = $('<div/>').text(rawResult).html();
					return {
						isError : true,
						errorMessage : safeErrorHtml
					};
				}
			}
		}
	}

	if (result.error) {
		// This is really what should happen; if there's an error, a
		// result.error object will
		// exist
		var safeErrorHtml = $('<div/>').text(result.error.message).html();
		return {
			isError : true,
			errorMessage : safeErrorHtml
		};
	} else if (result[0] && result[0].error) {
		// This is yet another hack; the DevAppServer incorrectly returns an
		// array of error
		// responses in the case where the endpoint method throws an app-level
		// exception.
		// Again, this will be fixed in a forthcoming version of App Engine.
		var safeErrorHtml = $('<div/>').text(result[0].error.message).html();
		return {
			isError : true,
			errorMessage : safeErrorHtml
		};
	}

	return {
		isError : false
	};
}

function generateRegDeviceTable(deviceInfoItems) {
	items = deviceInfoItems.items;

	if (!items || items.length == 0) {
		var htmlString = "<thead>" + "<tr>"
				+ "<th>There are no registered devices</th>" + "</tr>"
				+ "</thead>" + "<tbody></tbody>";
		$("#regDevicesTable").html(htmlString);
	} else {
		var htmlString = "<thead>" + "<tr>"
				+ "<th style='min-width:150px'>Device Name</th>"
				+ "<th>Registration Id</th>" + "<th>Timestamp</th>" + "</tr>"
				+ "</thead>" + "<tbody>";

		for (var i = 0; i < items.length; i++) {
			item = items[i];
			htmlString += "<tr>";
			if (item.deviceInformation) {
				htmlString += "<td class='devicenameCol'>"
						+ item.deviceInformation + "</td>";
			} else {
				htmlString += "<td class='devicenameCol'>" + "(unknown)"
						+ "</td>";
			}

			if (item.deviceRegistrationID) {
				htmlString += "<td class='deviceIdCol'>"
						+ item.deviceRegistrationID + "</td>";
			} else {
				htmlString += "<td class='deviceIdCol'>" + "(unknown)"
						+ "</td>";
			}

			if (item.timestamp) {
				var timestampNumberic = new Number(item.timestamp);
				var date = new Date(timestampNumberic);

				htmlString += "<td>" + date.toString() + "</td>";
			} else {
				htmlString += "<td>" + "(unknown)" + "</td>";
			}

			htmlString += "</tr>";
		}

		htmlString += "</tbody>";
		$("#regDevicesTable").html(htmlString);
	}
}

function updateRegisteredDeviceTable() {
	gapi.client.deviceinfoendpoint
			.listDeviceInfo({})
			.execute(
					function(deviceInfoItems, deviceInfoItemsRaw) {
						errorResult = checkErrorResponse(deviceInfoItems,
								deviceInfoItemsRaw);
						if (errorResult.isError) {
							showError("There was a problem contacting the server when attempting to list the registered devices. "
									+ "Please refresh the page and try again in a short while. Here's the error information:<br/> "
									+ errorResult.errorMessage);
						} else {
							generateRegDeviceTable(deviceInfoItems);
						}
					});
}

function handleMessageResponse(data, dataRaw) {
	errorResult = checkErrorResponse(data, dataRaw);
	if (!errorResult.isError) {
		showSuccess();
	} else {
		showError("There was a problem when attempting to send the message using the server at "
				+ API_URL
				+ ". "
				+ " Is your API Key in MessageEndpoint.java "
				+ "(in your App Engine project) set correctly? Here's the error information:<br/>"
				+ errorResult.errorMessage);
	}
}


// Sending the new policy to the GCM server. The GCM server itself will notify the devices.
function sendMessage() {
	var message = $("#inputMessage").val();

	if (message == "") {
		showInfo("Message must not be empty!");
	} else {
		gapi.client.messageEndpoint.sendMessage({
			"message" : message
		}).execute(handleMessageResponse);
	}
}